#ifndef MAIL_BOX_H
#define MAIL_BOX_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "03_list.h"
#include "03_queue.h"

#define ENTER_CRITICAL_AREA(mutex)  do{pthread_mutex_lock(mutex);}while(0)
#define QUIT_CRITICAL_AREA(mutex)  do{pthread_mutex_unlock(mutex);}while(0)

typedef struct mail_box_system
{
    pthread_mutex_t mutex;  //保护邮件系统
    LIST_LINK *thread_list;
}MBS;

extern MBS *mbs;

/***************************************************************
 *函数名: create_mail_box_system
 *功  能: 创建线程邮箱
 *参  数: 
 * 		无
 *返回值: 
 * 		成功返回创建好链表的指针
 * 		失败返回NULL
 *注意事项:
		无
 **************************************************************/
extern MBS *create_mail_box_system();
	
/***************************************************************
 *函数名: destroy_mail_box_system
 *功  能: 销毁线程邮箱
 *参  数: 
 * 		创建好的线程邮箱的头节点指针
 *返回值: 
 * 		返回0
 *
 *注意事项:
		无
 **************************************************************/
extern int destroy_mail_box_system(MBS *mbs);

/***************************************************************
 *函数名: get_th_name
 *功  能: 获取本个线程的名称
 *参  数: 
 * 		线程邮箱的头节点指针
 *返回值: 
 * 		成功返回查找到名称指针
 * 		失败返回NULL
 *注意事项:
 *		不能传入空指针
 ***************************************************************/
extern char *get_th_name(MBS *msb);

/***************************************************************
 *函数名: register_to_mail_system
 *功  能: 在线程邮箱中注册一个新的线程
 *参  数: 
 * 		线程邮箱的头节点指针，需要注册的线程名称，需要注册的线程函数接口
 *返回值: 
 * 		成功返回0
 * 		失败返回-1
 *注意事项:
 *		保证传入的三个参数之均不为空
 ***************************************************************/
extern int register_to_mail_system(MBS *mbs, char name[], th_fun th);

/***************************************************************
 *函数名: unregister_to_mail_system
 *功  能: 在线程邮箱中注销一个新的线程
 *参  数: 
 * 		线程邮箱的头节点指针，需要注销的线程名称，需要注销的线程函数接口
 *返回值: 
 * 		成功返回0
 * 		失败返回-1
 *注意事项:
 *		保证传入的三个参数之均不为空
 ***************************************************************/
extern int unregister_from_mailbox(MBS *msb, char *name);

/***************************************************************
 *函数名: wait_all_end
 *功  能: 等待所有的线程接受并为线程收尸
 *参  数: 
 * 		线程邮箱的头节点指针
 *返回值: 
 * 		返回0
 * 	
 *注意事项:
 *		不能传入空指针
 ***************************************************************/
extern int wait_all_end(MBS *msb);

/***************************************************************
 *函数名: send_msg
 *功  能: 给指定的线程发送数据
 *参  数: 
 * 		线程邮箱的头节点指针，接收线程的名称，数据结构
 *返回值: 
 * 		返回0
 * 	
 *注意事项:
 *		不能传入空指针,也不能传入线程邮箱中没有注册的线程名称
 ***************************************************************/
extern int send_msg(MBS *msb, char *recvname, DATATYPE data);

/***************************************************************
 *函数名: recv_msg
 *功  能: 去指定的线程邮箱提取数据
 *参  数: 
 * 		线程邮箱的头节点指针，发送线程的名称，数据结构
 *返回值: 
 * 		返回0
 * 	
 *注意事项:
 *		不能传入空指针,也不能传入线程邮箱中没有注册的线程名称
 ***************************************************************/
extern int recv_msg(MBS *msb, char *sendname, DATATYPE data);
#endif
